package org.lex.game.sudoku.view;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.ActionMap;
import javax.swing.BoundedRangeModel;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.border.TitledBorder;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

import org.lex.game.sudoku.SudokuApplication;
import org.lex.game.sudoku.datatype.SelectType;
import org.lex.game.sudoku.model.SudokuModel;
import org.lex.game.sudoku.util.table.LabelProvider;

public class HistoryBoard extends JPanel {
	private static final long serialVersionUID = 3898062803525879806L;

	private JSplitPane splitPane;
	private JPanel historyPane;
	private JPanel historyControlPane;
	private JScrollPane scrollPane;
	private JTable table;
	private CellHintPane hintPane;
	private HistoryTableModel tableModel;

	private final HistoryBoardController controller;

	/**
	 * Create the panel.
	 */
	public HistoryBoard(SudokuApplication app, SudokuModel sudokuModel) {
		this.controller = new HistoryBoardController(app, this, sudokuModel);
		this.initialize();
	}

	public void selectedCellChanged(SelectType type, int row, int column) {
		this.controller.selectedCellChanged(type, row, column);
	}

	private void initialize() {
		setLayout(new BorderLayout(0, 0));
		add(getSplitPane(), BorderLayout.CENTER);
	}

	private JSplitPane getSplitPane() {
		if (splitPane == null) {
			splitPane = new JSplitPane();
			splitPane.setName("hisrory_hintSplit");
			splitPane.setDividerSize(6);
			splitPane.setResizeWeight(0.7);
			splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
			splitPane.setLeftComponent(getHistoryPane());
			splitPane.setRightComponent(getHintPane());
		}
		return splitPane;
	}

	private JPanel getHistoryPane() {
		if (historyPane == null) {
			historyPane = new JPanel();
			historyPane.setBorder(new TitledBorder(null, "History", TitledBorder.CENTER, TitledBorder.TOP, null, null));
			historyPane.setLayout(new BorderLayout(0, 0));
			historyPane.add(getHistoryControlPane(), BorderLayout.NORTH);
			historyPane.add(getScrollPane(), BorderLayout.CENTER);
		}
		return historyPane;
	}

	private JPanel getHistoryControlPane() {
		if (historyControlPane == null) {
			historyControlPane = new JPanel();
			FlowLayout layout = new FlowLayout(FlowLayout.LEFT, 5, 0);
			layout.setAlignOnBaseline(true);
			historyControlPane.setLayout(layout);

			ActionMap am = this.controller.getActionMap();
			historyControlPane.add(new JButton(am.get(HistoryBoardController.MARK_ACTION)));
			historyControlPane.add(new JButton(am.get(HistoryBoardController.ROLLBACK_ACTION)));
		}
		return historyControlPane;
	}

	private JScrollPane getScrollPane() {
		if (scrollPane == null) {
			scrollPane = new JScrollPane();
			scrollPane.setAutoscrolls(true);
			scrollPane.setViewportView(getTable());
		}
		return scrollPane;
	}

	JTable getTable() {
		if (table == null) {
			table = new JTable(this.getTableModel());
			table.setFillsViewportHeight(true);
			table.setAutoCreateRowSorter(false);
			table.setRowSelectionAllowed(true);
			table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

			// auto scroll vertical scrollbar
			table.addComponentListener(new ComponentAdapter() {
				@Override
				public void componentResized(ComponentEvent e) {
					BoundedRangeModel model = getScrollPane().getVerticalScrollBar().getModel();
					model.setValue(model.getMaximum());
				}
			});

			// set default column widths & cell render
			LabelProvider<Operation> labelProvider = this.getTableModel().getLabelProvider();
			HistoryTableCellRender cellRender = new HistoryTableCellRender();
			TableColumnModel columnModel = table.getColumnModel();
			columnModel.getColumn(0).setPreferredWidth(26);
			columnModel.getColumn(0).setCellRenderer(cellRender);
			for (int col = 1, colCount = labelProvider.getColumnCount() + 1; col < colCount; col++) {
				TableColumn column = columnModel.getColumn(col);
				column.setPreferredWidth(labelProvider.getPreferredColumnWidth(col - 1));
				column.setCellRenderer(cellRender);
			}

			// add selection listener
			table.getSelectionModel().addListSelectionListener(this.controller);
		}
		return table;
	}

	HistoryTableModel getTableModel() {
		if (null == this.tableModel) {
			this.tableModel = new HistoryTableModel(new HistoryOperationLabelProvider(this.controller.getApplication()));
		}
		return tableModel;
	}

	CellHintPane getHintPane() {
		if (hintPane == null) {
			hintPane = new CellHintPane();
		}
		return hintPane;
	}
}
